package com.mxpio.erp.oa.service.impl;

import com.google.common.collect.Lists;
import com.mxpio.erp.common.enums.BizExceptionEnums;
import com.mxpio.erp.common.enums.OaEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.handler.WorkerOrderStatusManager;
import com.mxpio.erp.common.model.request.BpmnSubmitRequest;
import com.mxpio.erp.common.oa.entity.OaFixApply;
import com.mxpio.erp.common.oa.service.OaFixApplyService;
import com.mxpio.erp.common.util.AssertUtil;
import com.mxpio.erp.common.util.CloneUtil;
import com.mxpio.erp.common.util.JacksonMapUtils;
import com.mxpioframework.camunda.service.BpmnFlowService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.PojoDictParseService;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

;

@Service
public class OaFixApplyServiceImpl extends BaseServiceImpl<OaFixApply> implements OaFixApplyService {

        @Resource
        private BpmnFlowService bpmnFlowService;

        @Resource
        private PojoDictParseService dictService;

        @Override
        @Transactional(rollbackFor = Exception.class)
        public OaFixApply doSave(OaFixApply oaFixApply) {
            oaFixApply.setOrderStatus(OaEnums.OrderStatus.NEW.getCode());
            oaFixApply.setBpmnStatus(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode());
            this.save(oaFixApply);

            return oaFixApply;
        }

        @Override
        @Transactional
        public OaFixApply submit(BpmnSubmitRequest request) {

            AssertUtil.notEmpty(request.getBizNo(), BizExceptionEnums.PARAM_NOT_NULL, "bizNo");

            OaFixApply oaFixApplyOrder = this.getById(OaFixApply.class, request.getBizNo());

            AssertUtil.notNull(oaFixApplyOrder, BizExceptionEnums.ORDER_NOT_FOUND);

            WorkerOrderStatusManager.submitValidate(oaFixApplyOrder.getOrderStatus(), oaFixApplyOrder.getBpmnStatus());

            //1. 开启工作流
            OaFixApply oaFixApply = parseDict(oaFixApplyOrder);
            Map<String, Object> workFlowParam = JacksonMapUtils.convertObjectToMap(oaFixApply);
            ProcessInstance processInstance = bpmnFlowService.startWithFormByKey(request.getKey(), SecurityUtils.getLoginUsername(), request.getBusinessKey(),workFlowParam);
            //2. 更新工单
            oaFixApplyOrder.setOrderStatus(OaEnums.OrderStatus.UNDER_REVIEW.getCode());
            oaFixApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode());
            oaFixApplyOrder.setProcessInstanceId(processInstance.getId());
            this.update(oaFixApplyOrder);

            return oaFixApplyOrder;
        }

        @Override
        @Transactional
        public OaFixApply audit(BpmnSubmitRequest request) {

            AssertUtil.notEmpty(request.getBizNo(), BizExceptionEnums.PARAM_NOT_NULL, "bizNo");

            OaFixApply oaFixApplyOrder = this.getById(OaFixApply.class, request.getBizNo());

            AssertUtil.notNull(oaFixApplyOrder, BizExceptionEnums.ORDER_NOT_FOUND);

            List<String> passStatus = Lists.newArrayList(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode(),
                OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());

            AssertUtil.notNull(passStatus.contains(request.getBpmnStatus()),BizExceptionEnums.ORDER_AUDIT_STATUS_ERROR);

            //被审批工单允许的状态
            List<String> orderPassStatus = Lists.newArrayList(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode());

            AssertUtil.isTrue(orderPassStatus.contains(oaFixApplyOrder.getBpmnStatus()),BizExceptionEnums.ORDER_UNABLE_AUDIT_BY_STATUS,oaFixApplyOrder.getBpmnStatus());

            if (request.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())) {
                 oaFixApplyOrder.setOrderStatus(OaEnums.OrderStatus.DONE.getCode());
                 oaFixApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());
             }else{
                 oaFixApplyOrder.setOrderStatus(OaEnums.OrderStatus.CLOSED.getCode());
                 oaFixApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());
             }

             this.update(oaFixApplyOrder);

             return oaFixApplyOrder;
            }

        private OaFixApply parseDict(OaFixApply OaFixApplyOrder) {
            OaFixApply cloneOaFixApply = CloneUtil.deepClone(OaFixApplyOrder, OaFixApply.class);
            Result<OaFixApply> result = Result.OK(cloneOaFixApply);
            dictService.parseDictResult(result);
            return result.getResult();
        }
}